package org.flashamaphone.voices
{
	import flash.utils.ByteArray;
	
	import org.flashamaphone.buffer.SoundConstants;
	import org.flashamaphone.voices.waveformFactories.IWaveFactory;
	import org.flashamaphone.voices.waveformFactories.SineWaveFactory;
	
	/** 
	 * base voice, default to sine wave - pass in a factory for a different voice
	 */
	public class SimpleWaveform implements IVoice
	{
		public static const MULTIPLIER:Number = (2*Math.PI)/SoundConstants.SAMPLING_RATE;
		
		/** last position in cycle to get continuous sounding waveforms */
		protected var lastPositionInCycle:int = 0;
		
		/** wave generator */
		public var wave:IWaveFactory;
		
		/** 
		 * constructor
		 */
		public function SimpleWaveform(waveformFactory:IWaveFactory = null){
			if (waveformFactory) {
				wave = waveformFactory;
			} else {
				wave = new SineWaveFactory();
			}
		}
		
		/**
		 * get attack bytes
		 * 
		 * @param frequency
		 * @param duration (milliseconds)
		 * @return sound byteArray
		 */
		public function attack(freq:Number, milliseconds:Number):ByteArray {
			var returnBytes:ByteArray = new ByteArray();
			var numSamples:int = (milliseconds * SoundConstants.SAMPLING_RATE_MILLISECONDS);
			returnBytes = wave.cycle(freq, numSamples, wave.lastSampleIndex);
			return returnBytes;
		}
		
		/**
		 * get decay bytes
		 * 
		 * @param frequency
		 * @param duration (milliseconds)
		 * @return sound byteArray
		 */
		public function decay(freq:Number, milliseconds:Number):ByteArray {
			var returnBytes:ByteArray = new ByteArray();
			var numSamples:int = (milliseconds * SoundConstants.SAMPLING_RATE_MILLISECONDS);
			returnBytes = wave.cycle(freq, numSamples, wave.lastSampleIndex);
			return returnBytes;
		}
		
		/**
		 * get sustain bytes
		 * 
		 * @param frequency
		 * @param duration (milliseconds)
		 * @return sound byteArray
		 */
		public function sustain(freq:Number, milliseconds:Number):ByteArray {
			var returnBytes:ByteArray = new ByteArray();
			var numSamples:int = (milliseconds * SoundConstants.SAMPLING_RATE_MILLISECONDS);
			returnBytes = wave.cycle(freq, numSamples, wave.lastSampleIndex);
			return returnBytes;
		}
		
		/**
		 * get release bytes
		 * 
		 * @param frequency
		 * @param duration (milliseconds)
		 * @return sound byteArray
		 */
		public function release(freq:Number, milliseconds:Number):ByteArray {
			var returnBytes:ByteArray = new ByteArray();
			var numSamples:int = (milliseconds * SoundConstants.SAMPLING_RATE_MILLISECONDS);
			returnBytes = wave.cycle(freq, numSamples, wave.lastSampleIndex);
			return returnBytes;
		}
	}
}